package com.zjj.learn.designmodel.work.command;

public class CommandTest {

    public static void main(String[] args) {
        //声明一个遥控器对象
        RemoteControl control = new RemoteControl();
        //声明接收者
        TV tv = new TV();
        //给遥控器指定一个打开电视机的命令
        control.setCommand(new TurnOnTVCommand(tv));
        //执行命令
        control.pressButton();


        //给遥控器指定一个关闭电视机的命令
        control.setCommand(new TurnOffTVCommand(tv));
        //执行命令
        control.pressButton();
    }


    /**
     * 命令模式的使用
     *
     * 命令模式（Command Pattern）是一种行为型设计模式，它将请求与接收者解耦，能够让发送请求的对象和接收并处理请求的对象分开来。
     * 在命令模式中，一个"命令"对象封装了某个操作，以便将该操作的参数化、队列化或记录日志等，从而支持可撤销的操作。
     *
     * 它将请求封装成对象，从而可以根据不同的请求来参数化其他对象。
     *
     * 我们就以遥控器为例。遥控器有非常多的命令执行，例如打开电视、关闭电视等等。
     *
     * 命令模式由四个主要组成部分构成：
     *
     * 命令模式通常包含以下角色：
     *   1、Command：抽象命令类，声明执行命令的接口。
     *   2、ConcreteCommand：具体命令类，实现Command定义的接口，它会持有一个Receiver实例，并调用Receiver执行具体的操作。
     *   3、Receiver：接收者，知道怎么实现具体的业务操作。
     *   4、Invoker：调用者，持有一个命令(Command)列表，并在需要时发起对命令的请求(Request)，将请求发送到Command去执行请求。
     *
     * 代码实现：
     * 1.  Command（命令）：定义所有具体命令的接口，包括执行（Execute）和撤销（Undo）两个方法。
     *        见：{@link com.zjj.learn.designmodel.work.command.Command}
     * 2.  ConcreteCommand（具体命令）：实现Command接口，包括具体的业务逻辑，也可以调用Receiver对象。
     *        见：
     *           {@link com.zjj.learn.designmodel.work.command.TurnOffTVCommand}
     *           {@link com.zjj.learn.designmodel.work.command.TurnOnTVCommand}
     * 3.  Invoker（调用者）：持有Command对象，并在需要的时候调用Command的Execute方法。
     *        见：{@link com.zjj.learn.designmodel.work.command.RemoteControl}
     * 4.  Receiver（接收者）：提供具体的业务逻辑实现，被具体命令对象调用。
     *        见：{@link com.zjj.learn.designmodel.work.command.TV}
     *
     **/
}
